# -*- coding: utf-8 -*-
"""
任务相关API接口模块

包含任务的创建、状态查询、取消、停止等功能接口
"""

import uuid
from datetime import datetime

from flask import Blueprint, request, jsonify

# 创建蓝图
任务接口蓝图 = Blueprint('任务接口', __name__, url_prefix='/api/task')


def 初始化任务接口(任务执行器, 任务状态字典, 任务状态锁, 执行总结字典, 执行总结锁,
                   任务状态常量, 日志记录器, 创建任务, 获取任务状态, 更新任务状态, 浏览器自动化任务执行):
    """
    初始化任务接口，注入依赖
    """
    global _任务执行器, _任务状态字典, _任务状态锁, _执行总结字典, _执行总结锁
    global _任务状态常量, _日志记录器, _创建任务, _获取任务状态, _更新任务状态, _浏览器自动化任务执行

    _任务执行器 = 任务执行器
    _任务状态字典 = 任务状态字典
    _任务状态锁 = 任务状态锁
    _执行总结字典 = 执行总结字典
    _执行总结锁 = 执行总结锁
    _任务状态常量 = 任务状态常量
    _日志记录器 = 日志记录器
    _创建任务 = 创建任务
    _获取任务状态 = 获取任务状态
    _更新任务状态 = 更新任务状态
    _浏览器自动化任务执行 = 浏览器自动化任务执行


@任务接口蓝图.route('/启动任务', methods=['POST'])
def 启动任务接口():
    """
    启动自动化任务接口
    
    功能:
        接收任务参数，创建新任务并提交到线程池执行
    
    请求体:
        JSON格式，必须包含用户名和密码
    
    返回:
        包含任务ID、状态和消息的JSON响应
    """
    try:
        请求数据 = request.get_json()
        if not 请求数据:
            return jsonify({"错误": "请求体不能为空"}), 400

        # 调试：打印接收到的请求数据
        _日志记录器.info(f"接收到的请求数据: {请求数据}")
        _日志记录器.info(f"请求数据的键: {list(请求数据.keys()) if 请求数据 else 'None'}")

        # 验证必需参数
        必需参数列表 = ['用户名', '密码']
        for 参数名 in 必需参数列表:
            if 参数名 not in 请求数据:
                _日志记录器.error(f"缺少必需参数: {参数名}, 可用参数: {list(请求数据.keys())}")
                return jsonify({"错误": f"缺少必需参数: {参数名}"}), 400

        # 生成任务ID
        任务编号 = str(uuid.uuid4())



        # 创建任务
        _创建任务(任务编号, "浏览器自动化", 请求数据)

        # 提交任务到线程池
        _任务执行器.submit(_浏览器自动化任务执行, 任务编号, 请求数据)

        _日志记录器.info(f"任务 {任务编号} 已创建并提交执行，绑定用户名: {请求数据['用户名']}")

        return jsonify({
            "任务编号": 任务编号,
            "状态": "已创建",
            "消息": "任务已创建并开始执行"
        }), 201

    except Exception as 异常:
        _日志记录器.error(f"创建任务失败: {异常}")
        return jsonify({"错误": f"创建任务失败: {str(异常)}"}), 500


@任务接口蓝图.route('/任务状态/<task_id>', methods=['GET'])
def 获取任务状态接口(task_id: str):
    """
    获取任务状态接口
    
    参数:
        task_id: URL路径中的任务标识符
    
    功能:
        返回指定任务的详细状态信息
    
    返回:
        任务状态的JSON响应，如果任务不存在则返回404错误
    """
    任务编号 = task_id
    任务信息 = _获取任务状态(任务编号)
    if not 任务信息:
        return jsonify({"错误": "任务不存在"}), 404

    return jsonify(任务信息)


@任务接口蓝图.route('/任务列表', methods=['GET'])
def 获取任务列表接口():
    """
    获取所有任务列表接口
    
    功能:
        返回系统中所有任务的列表，按创建时间倒序排列
    
    返回:
        包含任务列表和总数的JSON响应
    """
    with _任务状态锁:
        任务列表 = list(_任务状态字典.values())

    # 按创建时间排序（最新的在前）
    任务列表.sort(key=lambda x: x['创建时间'], reverse=True)

    return jsonify({
        "任务列表": 任务列表,
        "总数": len(任务列表)
    })


@任务接口蓝图.route('/取消任务/<task_id>', methods=['POST'])
def 取消任务接口(task_id: str):
    """
    取消任务接口
    
    参数:
        task_id: URL路径中的任务标识符
    
    功能:
        将指定任务标记为已取消状态
        注意：已运行的任务无法强制停止
    
    返回:
        操作结果的JSON响应
    """
    任务编号 = task_id
    任务信息 = _获取任务状态(任务编号)
    if not 任务信息:
        return jsonify({"错误": "任务不存在"}), 404

    if 任务信息['状态'] in [_任务状态常量.已完成, _任务状态常量.执行失败, _任务状态常量.已取消]:
        return jsonify({"错误": "任务已完成，无法取消"}), 400

    _更新任务状态(任务编号, _任务状态常量.已取消)

    return jsonify({
        "任务编号": 任务编号,
        "状态": "已取消",
        "消息": "任务已标记为取消"
    })


@任务接口蓝图.route('/停止任务', methods=['POST'])
def 停止任务接口():
    """
    停止OCR任务接口
    
    功能:
        停止当前正在运行的OCR任务
    
    返回:
        操作结果的JSON响应
    """
    try:
        # 获取当前运行中的任务
        with _任务状态锁:
            运行中任务 = [任务编号 for 任务编号, 任务信息 in _任务状态字典.items()
                          if 任务信息['状态'] == _任务状态常量.执行中]

        if not 运行中任务:
            return jsonify({
                "状态": "失败",
                "消息": "当前没有运行中的任务"
            }), 400

        # 标记所有运行中的任务为已取消
        for 任务编号 in 运行中任务:
            _更新任务状态(任务编号, _任务状态常量.已取消)
            _日志记录器.info(f"任务 {任务编号} 已被用户停止")

        return jsonify({
            "状态": "成功",
            "消息": f"已停止 {len(运行中任务)} 个运行中的任务",
            "停止的任务数量": len(运行中任务)
        })

    except Exception as 异常:
        _日志记录器.error(f"停止任务失败: {异常}")
        return jsonify({
            "状态": "失败",
            "消息": f"停止任务失败: {str(异常)}"
        }), 500


@任务接口蓝图.route('/提交执行总结/<task_id>', methods=['POST'])
def 提交执行总结接口(task_id: str):
    """
    提交执行总结接口
    
    参数:
        task_id: URL路径中的任务标识符
    
    功能:
        接收并保存任务的执行总结信息，供前端展示使用
    
    请求体:
        JSON格式，包含执行总结信息
    
    返回:
        操作结果的JSON响应
    """
    任务编号 = task_id
    try:
        请求数据 = request.get_json()
        if not 请求数据:
            return jsonify({"错误": "请求体不能为空"}), 400

        # 验证任务是否存在
        with _任务状态锁:
            if 任务编号 not in _任务状态字典:
                return jsonify({"错误": "任务不存在"}), 404

        # 构建执行总结数据
        执行总结数据 = {
            '任务编号': 任务编号,
            '提交时间': datetime.now().isoformat(),
            '执行用户': 请求数据.get('执行用户', '未知'),
            '执行状态': 请求数据.get('执行状态', '未知'),
            '开始时间': 请求数据.get('开始时间'),
            '完成时间': 请求数据.get('完成时间'),
            '个人待办数量': 请求数据.get('个人待办数量', 0),
            '暂不处理数量': 请求数据.get('暂不处理数量', 0),
            '处理单据总数': 请求数据.get('处理单据总数', 0),
            '处理成功数量': 请求数据.get('处理成功数量', 0),
            '处理失败数量': 请求数据.get('处理失败数量', 0),
            '处理单据列表': 请求数据.get('处理单据列表', []),
            '错误信息': 请求数据.get('错误信息'),
            '错误详情': 请求数据.get('错误详情'),
            '执行日志': 请求数据.get('执行日志', [])
        }

        # 存储执行总结
        with _执行总结锁:
            _执行总结字典[任务编号] = 执行总结数据

        # 更新任务状态中的执行总结标记
        _更新任务状态(任务编号, None, 执行总结=执行总结数据)

        _日志记录器.info(f"任务 {任务编号} 执行总结已更新")

        return jsonify({
            "消息": "执行总结提交成功",
            "任务编号": 任务编号
        })

    except Exception as 异常:
        _日志记录器.error(f"提交执行总结失败: {异常}")
        return jsonify({"错误": f"提交执行总结失败: {str(异常)}"}), 500


@任务接口蓝图.route('/获取执行总结/<task_id>', methods=['GET'])
def 获取执行总结接口(task_id: str):
    """
    获取执行总结接口
    
    参数:
        task_id: URL路径中的任务标识符
    
    功能:
        返回指定任务的执行总结信息
    
    返回:
        执行总结的JSON响应
    """
    任务编号 = task_id
    try:
        with _执行总结锁:
            if 任务编号 not in _执行总结字典:
                return jsonify({"错误": "执行总结不存在"}), 404

            执行总结数据 = _执行总结字典[任务编号]

        return jsonify({
            "状态": "成功",
            "任务编号": 任务编号,
            "执行总结": 执行总结数据
        })

    except Exception as 异常:
        _日志记录器.error(f"获取执行总结失败: {异常}")
        return jsonify({"错误": f"获取执行总结失败: {str(异常)}"}), 500


@任务接口蓝图.route('/获取所有执行总结', methods=['GET'])
def 获取所有执行总结接口():
    """
    获取所有执行总结接口
    
    功能:
        返回所有任务的执行总结列表
    
    返回:
        包含所有执行总结的JSON响应
    """
    try:
        with _执行总结锁:
            所有总结 = dict(_执行总结字典)

        return jsonify({
            "状态": "成功",
            "执行总结列表": 所有总结,
            "总数": len(所有总结)
        })

    except Exception as 异常:
        _日志记录器.error(f"获取所有执行总结失败: {异常}")
        return jsonify({"错误": f"获取所有执行总结失败: {str(异常)}"}), 500
